package com.platform.user.controller;

import com.platform.common.annotation.ApiResponseBody;
import com.platform.common.annotation.UserSession;
import com.platform.common.entity.UserSessionDTO;
import com.platform.common.enums.RoleEnum;
import com.platform.common.result.ApiException;
import com.platform.common.result.ApiExceptionEnum;
import com.platform.common.util.JwtUtils;
import com.platform.user.dto.UpdateNicknameDTO;
import com.platform.user.dto.UpdatePasswordDTO;
import com.platform.user.model.UserDO;
import com.platform.user.service.UserService;
import com.platform.user.vo.LoginVO;
import com.platform.user.vo.UserInfoVO;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * @author GH
 */
@ApiResponseBody
@Controller
@RequestMapping("/user")
public class UserController {

    @Resource
    private UserService userService;

    @Resource
    private JwtUtils jwtUtils;

    @GetMapping("/logout")
    public Void logout(HttpServletResponse response) {
        response.setHeader(UserSessionDTO.HEADER_KEY, UserSessionDTO.HEADER_VALUE_LOGOUT);
        return null;
    }


    @PostMapping("/login")
    public LoginVO login(@RequestHeader("User-Agent") String userAgent,
                         @RequestBody Map<String, String> requestBody) {
        String account = requestBody.get("account");
        String password = requestBody.get("password");
        UserDO userDO = userService.getByAccount(account);
        if (!password.equals(userDO.getPassword())) {
            throw new ApiException(ApiExceptionEnum.PASSWORD_NOT_MATCHING);
        }

        UserSessionDTO userSessionDTO = UserDO.toUserSessionDTO(userDO, "", userAgent);
        return UserDO.toLoginVO(userDO, jwtUtils.getAndCacheJwtToken(userSessionDTO));
    }

    @PostMapping("/register")
    public Boolean register(@RequestBody Map<String, String> requestBody) {
        String account = requestBody.get("account");
        String password = requestBody.get("password");
        String nickname = requestBody.get("nickname");
        boolean exist = userService.isExist(account);
        if (exist) {
            throw new ApiException(ApiExceptionEnum.USER_ACCOUNT_ALREADY_EXIST);
        }

        UserDO newUserDO = UserDO.builder()
                .account(account)
                .password(password)
                .nickname(nickname)
                .role(RoleEnum.USER.getName())
                .build();
        Boolean result = userService.save(newUserDO);
        if (!result) {
            throw new ApiException(ApiExceptionEnum.DB_FAIL);
        }
        return true;
    }

    @GetMapping("/info")
    public UserInfoVO info(@UserSession UserSessionDTO userSessionDTO) {
        String id = userSessionDTO.getId();
        UserDO userDO = userService.getById(id);
        return UserDO.toUserInfoVO(userDO);
    }

    @PutMapping("/updatePwd")
    public Boolean updatePassword(@UserSession UserSessionDTO userSessionDTO,
                                  @RequestBody UpdatePasswordDTO updatePasswordDTO) {
        String id = userSessionDTO.getId();
        String oldPassword = updatePasswordDTO.getOldPassword();
        String newPassword = updatePasswordDTO.getNewPassword();
        UserDO userDO = userService.getPasswordById(id);
        if (oldPassword == null ||
                !oldPassword.equals(userDO.getPassword())) {
            throw new ApiException(ApiExceptionEnum.PASSWORD_NOT_MATCHING);
        }
        userDO.setPassword(newPassword);
        Boolean result = userService.updateById(userDO);
        if (!result) {
            throw new ApiException(ApiExceptionEnum.DB_FAIL);
        }
        return true;
    }

    @PutMapping("/updateNickname")
    public Boolean updateNickname(@UserSession UserSessionDTO userSessionDTO,
                                  @RequestBody UpdateNicknameDTO updateNicknameDTO) {
        String id = userSessionDTO.getId();
        String nickname = updateNicknameDTO.getNickname();
        UserDO userDO = userService.getNicknameById(id);
        userDO.setNickname(nickname);
        Boolean result = userService.updateById(userDO);
        if (!result) {
            throw new ApiException(ApiExceptionEnum.DB_FAIL);
        }
        return true;
    }
}

